import datetime
from datetime import timezone

from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Float
from sqlalchemy.orm import relationship

from database import Base


class User(Base):
    __tablename__ = "users"
    '''
    在 SQLAlchemy 中，index=True 是用来创建数据库索引的一个参数。
    当你在定义一个列时，如果给列加上 index=True，它会在数据库中为该列创建一个索引。
    
    索引的作用：
    1、提高查询效率：索引可以显著加速对数据库表的查询操作，
        特别是在你经常通过某个列进行查询时。例如，如果你经常根据 user_id 查询订单，那么给 user_id 列加上索引会加速查询。
    2、加速排序操作：如果查询中有排序（ORDER BY）操作，并且排序字段上有索引，那么数据库可以通过索引更快速地返回结果。
    3、唯一性：虽然 index=True 本身不保证唯一性，但它是创建唯一索引的前提条件之一。如果你希望某列的值唯一，通常会使用 unique=True，但也可以与 index=True 结合使用。
    '''
    id = Column(Integer, primary_key=True, index=True)
    username = Column(String(50), unique=False, index=True, nullable=False)
    email = Column(String(100), unique=True, index=True, nullable=False)
    full_name = Column(String(100))
    created_at = Column(DateTime, default=lambda: datetime.datetime.now(timezone.utc))
    updated_at = Column(DateTime, default=lambda: datetime.datetime.now(timezone.utc),
                        onupdate=lambda: datetime.datetime.now(timezone.utc))
    '''
    在SQLAlchemy ORM中，`orders = relationship("Order", back_populates="user")` 定义了User模型与Order模型之间的一对多关系。这行代码的作用是：

    1. 在User类中创建一个名为`orders` 的属性，它将包含与该用户关联的所有订单对象的集合
    2. `back_populates="user"` 表示在Order模型中有一个名为`user` 的属性，它指向关联的User对象
    3. 这种双向关系使得可以从用户访问其所有订单(`user.orders` )，也可以从订单访问其所属用户(`order.user` )
    4. 这种关系映射使得在查询时可以轻松地进行连接查询，如使用`joinedload(User.orders)` 预加载用户的所有订单
    5. 当删除用户时，可以通过这种关系轻松找到并处理关联的订单，实现级联操作
    '''
    orders = relationship("Order", back_populates="user")

    def __repr__(self):
        return f"<User(id={self.id}, username={self.username}, email={self.email})>"


class Order(Base):
    __tablename__ = "orders"

    id = Column(Integer, primary_key=True, index=True)
    product = Column(String(255))
    amount = Column(Float)
    # 表示orders表的user_id字段和users表的id关联
    user_id = Column(Integer, ForeignKey("users.id"))
    created_at = Column(DateTime, default=lambda: datetime.datetime.now(timezone.utc))
    updated_at = Column(DateTime, default=lambda: datetime.datetime.now(timezone.utc),
                        onupdate=lambda: datetime.datetime.now(timezone.utc))
    user = relationship("User", back_populates="orders")
